package com.sensetime.jv.annotation;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sensetime.jv.entity.UrlPermissionDTO;
import com.sensetime.jv.entity.UrlPermissionsJv;
import com.sensetime.jv.mapper.UrlPermissionsMapper;
import com.sensetime.jv.util.RedisCache;
import com.sensetime.jv.util.RedisLock;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class PermissionSyncHelper {

    private final UrlPermissionsMapper urlPermissionMapper;
    private final RedisCache redisCache;

    @Value("${redis.cache.custom.urlTokenKey}")
    private String lockKey;

    @Value("${redis.cache.custom.urlTokenKeyLock}")
    private String cacheUrlLock;       // 存储白名单路径的值

    /**
     * 判断是否应该跳过
     */
    public boolean shouldSkip(String url, String method, String servletPath) {
        String key = url + method + servletPath;
        String redisKey = lockKey + key;
        return Boolean.TRUE.equals(redisCache.getRedisTemplate().hasKey(redisKey));
    }

    public void syncPermissionsBatchLock(List<UrlPermissionDTO> dtos) {
        RedisLock.executeWithLock(cacheUrlLock,()->syncPermissionsBatch(dtos));

    }


    /**
     * 公共批量同步方法
     */
    public void syncPermissionsBatch(List<UrlPermissionDTO> dtos) {
        if (CollectionUtils.isEmpty(dtos)) return;

        // 1. key -> dto
        Map<String, UrlPermissionDTO> dtoMap = dtos.stream()
                .collect(Collectors.toMap(
                        d -> d.getUrl() + ":" + d.getMethod(),
                        d -> d,
                        (a, b) -> a));

        // 2. 查询现有记录
        List<UrlPermissionsJv> dbRecords = urlPermissionMapper.selectList(Wrappers.lambdaQuery());
        Map<String, UrlPermissionsJv> dbMap = dbRecords.stream()
                .collect(Collectors.toMap(
                        r -> r.getUrl() + ":" + r.getMethod(),
                        r -> r,
                        (a, b) -> a));

        // 3. 分类
        List<UrlPermissionsJv> toInsert = new ArrayList<>();
        List<UrlPermissionsJv> toUpdate = new ArrayList<>();
        List<Integer> toDelete = new ArrayList<>();

        for (UrlPermissionDTO dto : dtos) {
            String key = dto.getUrl() + ":" + dto.getMethod();
            UrlPermissionsJv db = dbMap.get(key);

            UrlPermissionsJv record = new UrlPermissionsJv();
            BeanUtils.copyProperties(dto, record);

            if (db == null) {
                toInsert.add(record);
            } else {
                record.setId(db.getId());
                toUpdate.add(record);
            }
        }

        for (UrlPermissionsJv db : dbRecords) {
            String key = db.getUrl() + ":" + db.getMethod();
            if (!dtoMap.containsKey(key)) {
                toDelete.add(db.getId());
            }
        }

        // 4. 执行
        toInsert.forEach(urlPermissionMapper::insert);
        toUpdate.forEach(urlPermissionMapper::updateById);
//        toDelete.forEach(urlPermissionMapper::deleteById);

        // 5. 写 Redis
        dtos.forEach(d -> {
            String key = d.getUrl() + d.getMethod() + d.getServletPath();
            String redisKey = lockKey + key;
            redisCache.setCacheObject(redisKey, 1);
        });
    }

}